import { appAddSvr, parseArgs } from "./util/util";
import { AppCfg, MsgCfg, SvrCfg, SvrInfo } from "./util/defines";
import { Application } from "./Application";
import { coder } from "./util/coder";
import { FrontendSession } from "./session/FrontendSession";
import { logger } from "./util/logger";

/**
 * Application初始化
 */
export class AppIniter {

    app: Application;

    constructor(app: Application, cfg: AppCfg) {
        this.app = app;
        app.miscCfg.msgCoder = coder;
        let args = parseArgs(process.argv);
        app.env = args.env || app.env;
        app.isTs = app.main.endsWith(".ts");
        this.loadSvrCfg(cfg.svrCfg);
        this.loadMsgCfg(cfg.msgCfg);
        this.processArgs(args);
    }

    /**
     * 读取服务器配置
     * @param cfg 
     */
    loadSvrCfg(cfg: SvrCfg) {
        let envCfg = cfg[this.app.env];
        if (!envCfg) {
            logger.error(`${this.app.env}环境服务器配置不存在`, this, this.loadSvrCfg);
            process.exit();
        }
        try {
            let { master, servers } = envCfg;
            this.app.masterCfg = {
                id: master.id,
                type: "master",
                host: master.host,
                port: master.port || 6606,
                isFrontend: false,
                args: master.args
            };
            this.app.svrCfg = {};
            this.app.svrCfgIdMap = {};
            for (let stype in servers) {
                this.app.svrCfg[stype] = [];
                this.app.setSvrRouter(stype, this.defaultSvrRouter);
                for (let svr of servers[stype]) {
                    let info: SvrInfo = {
                        id: svr.id,
                        type: stype,
                        host: svr.host,
                        port: svr.port,
                        isFrontend: !!svr.clientPort,
                        clientPort: svr.clientPort,
                        args: svr.args
                    };
                    this.app.svrCfg[stype].push(info);
                    this.app.svrCfgIdMap[svr.id] = info;
                }
            }
        } catch (err: any) {
            logger.error("服务器配置加载失败:" + err.stack, this, this.loadSvrCfg);
            process.exit();
        }
    }

    /**
     * 读取消息路由配置
     * @param cfg 
     */
    loadMsgCfg(cfg: MsgCfg) {
        try {
            this.app.msgCfg = {};
            for (let msgId in cfg) {
                this.app.msgCfg[msgId] = cfg[msgId].split(".");
            }
        } catch (err: any) {
            logger.error("消息路由配置加载失败: " + err.stack, this, this.loadMsgCfg);
        }
    }

    /**
     * 处理启动参数
     * @param args 
     */
    processArgs(args: any) {
        let svrId = args.id || this.app.masterCfg.id;
        if (svrId === this.app.masterCfg.id) {
            this.app.isMaster = true;
            this.app.svr = this.app.masterCfg;
            this.app.stype = this.app.masterCfg.type;
        } else {
            this.app.isMaster = false;
            let svr = this.app.svrCfgIdMap[args.id];
            if (!svr) {
                logger.error("未找到服务器配置: " + args.id, this, this.processArgs);
                process.exit();
            }
            this.app.svr = svr;
            this.app.stype = svr.type;
            appAddSvr(this.app, svr);
        }
    }

    /**
     * 默认服务器路由
     */
    private defaultSvrRouter(sess: FrontendSession, svrCfgs: SvrInfo[]) {
        return svrCfgs[sess.uid % svrCfgs.length];
    }
}